﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Taobao.Top.Api.Request;
using Taobao.Top.Api.Domain;
using Model = TaobaoDistrSales.Model;
using System.Threading;
using System.Drawing;
using System.Configuration;
using System.Windows.Forms;

namespace TaobaoDistrSales.Common
{
    public class TaobaoFeiXiaoProcessor : TaobaoProcessor
    {
        #region Ctors

        public TaobaoFeiXiaoProcessor(short shopid)
            : base(shopid)
        {
        }

        public TaobaoFeiXiaoProcessor(short shopid, IOutputWriter writer)
            : base(shopid, writer)
        {
        }

        #endregion

        #region Switch Shop

        public Func<Model.Shop, short> SwitchShop;

        #endregion

        #region Override Methods

        protected override void DoExcuteJob()
        {
            string msg = "starting";
            try
            {
                OnProcessStarted();
                
#if NEEDAUTH
                var result = AuthorizationProvider.Current.Authorize(Shop.Name);
#else
                var result = new AuthorizationResult() { Status = "yes" };
#endif
                if (result==null || !result.Status.Equals("yes", StringComparison.OrdinalIgnoreCase))
                {
                    throw new Exception(result == null ? "店铺未经授权" : result.Info);
                }
                //if (!AuthorizationProvider.Current.Authorize(Shop.Name))
                //{
                //    MessageBox.Show("对不起，您的程序未经授权，不能使用！");
                //    Application.Exit();
                //    return;
                //}

#if !DEBUG
                //更新评价
                if(ResourceManager.Current.OptionsConfig.updateTradeRate)
                    ExcuteUpdateTradeRates();
#endif
                SendDeliveries();
#if !DEBUG
                if (ResourceManager.Current.OptionsConfig.updateRefund)
                    UpdateRefunds();  
                if (ResourceManager.Current.OptionsConfig.updateNotFinishedTrade)
                    UpdateNotFinishedTradeInfosFromTAOBAO();              
#endif

                if (ResourceManager.Current.OptionsConfig.downloadTrade)
                {
                    DownloadTrades();
                    DownloadPurchaseOrderWithoutTrade();
                }
                if (ResourceManager.Current.OptionsConfig.updatePurchaseOrder)
                    UpdatePurchaseOrders();

                UpdatePurchaseSubOrders();

                SaveTradesDeliveries();

                SavePurchaseOrdersDeliveries();
#if !DEBUG
                SendDeliveries();
#endif
                OnProcessCompleted();
                msg = "completed";  
            }
            catch (Exception e)
            {
                HandleException("程序运行中出错:"+e.Message, e);
            }
            finally
            {
                try
                {
                    if (ResourceManager.Current.OptionsConfig.clearoutput)
                    {
                        Thread.Sleep(ThreadSleepTick);
                        OutputWriter.Clear();
                        Thread.Sleep(ThreadSleepTick);
                    }

                    if (msg == "completed")
                    {
                        if (SwitchShop != null )
                        {
                            var sp = SwitchShop(Shop);
                            using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                            {
                                var newShop = (from s in entities.Shop
                                               where s.ShopId == sp
                                               select s).FirstOrDefault();
                                if (newShop != null)
                                    ShopID = newShop.ShopId;
                            }
                        }
                        
#if !DEBUG
                        var interval = ResourceManager.Current.OptionsConfig.processinterval * 60;
                        var hours = ResourceManager.Current.OptionsConfig.processinterval / 60;
                        var minutes = ResourceManager.Current.OptionsConfig.processinterval % 60;
                        var seconds = 0;
                        while (interval-- > 0 && msg == "completed")
                        {
                            hours = interval / (60 * 60);
                            minutes = (interval % (60 * 60)) / 60;
                            seconds = interval % 60;
                            TimeSpan timeSpan = new TimeSpan(hours, minutes, seconds);
                            ExcuteUpdateStatus("程序将在:" + timeSpan.ToString() + " 后重新自动执行。");
                            Thread.Sleep(1000);
                        }
#endif
                    }
                }
                catch (Exception error)
                {
                    HandleException("程序重新运行中出错。", error);
                    ExcuteUpdateStatus("程序将重新自动执行。");
                }
                finally
                {
                    DoExcuteJob();
                }
            }
        }

        #endregion

        #region Update From Taobao

        /// <summary>
        /// Update the Distributors From TAOBAO to DataBase
        /// </summary>
        /// <param name="nicks"></param>
        protected void UpdateDistributors(string nicks)
        {
            ExcuteUpdateStatus("开始更新分销商信息");

            try
            {
                OutputWriter.WriteLine("开始更新分销商信息！", OutputFormatType.Title);
                FenXiaoGetDistributorsRequest request = new FenXiaoGetDistributorsRequest();
                request.Nicks = nicks;
                var firstRefunds = Client.FenXiaoGetDistributors(request,SessionKey);

            }
            catch (Exception e)
            {
                HandleException("更新分销商信息失败。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新分销商信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        /// <summary>
        /// Update the Refund Information from TAOBAO to Database
        /// </summary>
        protected void UpdateRefunds()
        {
            long total = 0;
            long success = 0;
            string title = "分销采购单的退款信息";
            ExcuteUpdateStatus("正在更新分销采购单的退款信息");
            try
            {
                OutputWriter.WriteLine("开始更新分销的退款采购单！", OutputFormatType.Title);

                RefundsReceiveGetRequest request = new RefundsReceiveGetRequest();
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Fields = "refund_id, tid, title, buyer_nick, seller_nick, total_fee, status, created, refund_fee, oid, good_status, company_name, sid, payment, reason, desc, has_good_return, modified, order_status ";
                request.Type = "fenxiao";
                PageList<Refund> firstRefunds = Client.RefundsReceiveGet(request, SessionKey);

                LogstatisticsStart(title, total = firstRefunds.TotalResults);

                success = ProcessPageList<Refund>("分销采购单的退款信息", request.PageSize.Value, firstRefunds,
                    (pageNo) =>
                    {
                        request.PageNo = pageNo;
                        return Client.RefundsReceiveGet(request, SessionKey);
                    },
                    SaveRefund);

            }
            catch (Exception e)
            {
                HandleException("更新分销采购单的退款信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        protected void UpdatePurchaseOrders()
        {
            long total = 0, success = 0;
            string title = "未发货交易的分销采购单";
            ExcuteUpdateStatus("开始更新未发货交易的分销采购单");
            try
            {
                OutputWriter.WriteLine("开始更新所有未发货交易的分销采购单...", OutputFormatType.Title);
                List<long> dTradeIdList = new List<long>();
                var date = DateTime.Now.AddMonths(-12);
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    dTradeIdList = (from t in entities.Trade
                                    where t.Shop.ShopId == ShopID
                                    && ((t.created != null && t.created.Value > date) || t.type == null)
                                    && t.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                    select t.tid).ToList();
                }

                LogstatisticsStart(title, total = dTradeIdList.Count);
                foreach (long tradeId in dTradeIdList)
                {
                    success += UpdatePurchaseOrders(tradeId) ? 1 : 0;
                        
                }
            }
            catch (Exception e)
            {
                HandleException("更新所有未发货交易的分销采购单失败", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        /// <summary>
        /// Update the Purchase Orders From TAOBAO to Database
        /// </summary>
        protected bool UpdatePurchaseOrders(long dTradeId)
        {
            int total = 0;
            int success = 0;
            try
            {
                //OutputWriter.WriteLine("开始更新交易:"+dTrade.tid+"的分销采购单。", OutputFormatType.Title);

                FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                request.PurchaseOrderID = dTradeId;
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;// "WAIT_SELLER_SEND_GOODS";
                PageList<PurchaseOrder> firstPurchaseOrderList = Client.FenXiaoGetOrders(request, SessionKey);
                if (firstPurchaseOrderList.Content.Count > 0)
                {
                    if (SavePurchaseOrder(firstPurchaseOrderList.Content[0], true))
                        success++;
                }

            }
            catch (Exception e)
            {
                HandleException("更新交易:" + dTradeId + "的分销采购单异常。", e);
            }
            finally
            {
            }
            return success > 0;
        }

        /// <summary>
        /// Update the Purchase Sub Orders from TAOBAO to Database
        /// </summary>
        protected void UpdatePurchaseSubOrders()
        {
            long total = 0, success = 0, subTotal = 0;
            string title = "分销采购单的子采购单信息";
            ExcuteUpdateStatus("开始更新分销采购单的子采购单信息");
            try
            {
                OutputWriter.WriteLine("开始更新分销采购单的子采购单...", OutputFormatType.Title);

                var allPurchaseOrderIdList= new List<long>();
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    if (ResourceManager.Current.OptionsConfig.updateDetailOrder)
                    {
                        allPurchaseOrderIdList = (from o in entities.PurchaseOrder
                                                  where o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                                  && o.Shop.ShopId == ShopID
                                                  select o.id).ToList();
                    }
                    else
                    {
                        allPurchaseOrderIdList = (from o in entities.PurchaseOrder
                                                  where o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                                  && o.Shop.ShopId == ShopID
                                                  && o.SubPurchaseOrderCount > 0
                                                  && o.SubPurchaseOrder.Count <= 0
                                                  select o.id).ToList();
                    }
                }
                total = allPurchaseOrderIdList.Count;
                OutputWriter.WriteLine("总共有：" + allPurchaseOrderIdList.Count + "分销采购单的子采购单需要更新。", OutputFormatType.Title);

                allPurchaseOrderIdList.ForEach(oid =>
                {
                    int t = 0, s = 0;
                    try
                    {
                        FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                        request.PageSize = 100;
                        request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;// "WAIT_SELLER_SEND_GOODS";
                        request.PurchaseOrderID = oid;
                        PageList<PurchaseOrder> orders = Client.FenXiaoGetOrders(request, SessionKey);

                        if (orders.Content.Count > 0)
                        {
                            var torder = orders.Content[0];
                            var subOrders = torder.SubPurchaseOrders;
                            t += subOrders.Count;
                            if (subOrders != null && subOrders.Count() > 0)
                            {
                                foreach (var tsubOrder in subOrders)
                                {
                                    try
                                    {
                                        if (SaveSubPurchaseOrder(oid, tsubOrder, true))
                                            s++;
                                    }
                                    catch (Exception e)
                                    {
                                        HandleException("更新分销采购单:" + oid + "的子采购单:" + tsubOrder.ID + "失败.", e);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        HandleException("更新分销采购单:" + oid + "的子采购单失败.", e);
                    }
                    OutputWriter.WriteLine("分销采购单:" + oid + " 一共有:" + t + "条子采购单，成功更新了：" + s + "条。", OutputFormatType.Title);

                    subTotal += t;
                    success += s;
                });

            }
            catch (Exception e)
            {
                HandleException("更新分销采购单的子采购单异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("一共有：" + total + "条未发货的分销采购单，其中包含了：" + subTotal + " 条子采购单，成功更新了：" + success + "条子采购单。", OutputFormatType.Title);
                OutputWriter.WriteLine("结束更新分销采购单的子采购单！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        protected void DownloadTrades()
        {
            long total = 0;
            long success = 0;
            string title = "分销交易信息";
            ExcuteUpdateStatus("正在更新分销交易信息");
            try
            {
                OutputWriter.WriteLine("开始更新分销交易信息...", OutputFormatType.Title);

                TradesSoldGetRequest request = new TradesSoldGetRequest();
                request.Type = Constants.TradeType_FenXiao;
                request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Fields = "title, type, created, sid, tid,end_time, received_payment, alipay_no, num_iid, num, price, shipping_type";
                request.StartCreated = DateTime.Now.AddMonths(-6);// new DateTime?(DateTime.Parse("1990.01.01"));
                request.EndCreated = new DateTime?(DateTime.Now);
                PageList<Trade> firstTradeList = Client.TradesSoldGet(request, SessionKey);

                LogstatisticsStart(title, total = firstTradeList.TotalResults);

                success = ProcessPageList<Trade>("分销交易信息", request.PageSize.Value,
                    firstTradeList,
                    (pageNo) =>
                    {
                        request.PageNo = pageNo;
                        return Client.TradesSoldGet(request, SessionKey);
                    },
                    SaveFullTrade
                    );

            }
            catch (Exception e)
            {
                HandleException("更新分销交易信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        protected void DownloadPurchaseOrderWithoutTrade()
        {
            long total = 0;
            long success = 0;
            string title = "分销流水号信息";
            ExcuteUpdateStatus("正在更新分销流水号信息");
            try
            {
                OutputWriter.WriteLine("开始更新分销流水号信息...", OutputFormatType.Title);

                var beforeDays = ResourceManager.Current.OptionsConfig.updatePurchaseOrderGetBeforeDays;
                beforeDays = beforeDays <= 0 ? 12 : beforeDays;
                var totalCount = (int)Math.Ceiling(beforeDays / 6.0);
                var currentDateTime = DateTime.Now;
                for (var i = 0; i < totalCount; i++)
                {
                    FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                    request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                    request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;// "WAIT_SELLER_SEND_GOODS";
                    request.StartCreated = (i < totalCount - 1) ? currentDateTime.AddDays(-(i + 1) * 6) : currentDateTime.AddDays(-beforeDays);// new DateTime?(DateTime.Parse("1990.01.01"));
                    request.EndCreated = currentDateTime.AddDays(-i * 6);
                    //request.TimeType = "";
                    PageList<PurchaseOrder> firstPurchaseOrderList = Client.FenXiaoGetOrders(request, SessionKey);

                    LogstatisticsStart(title, total = firstPurchaseOrderList.TotalResults);

                    success = ProcessPageList<PurchaseOrder>("分销流水号信息", request.PageSize.Value,
                        firstPurchaseOrderList,
                        (pageNo) =>
                        {
                            try
                            {
                                request.PageNo = pageNo;
                                return Client.FenXiaoGetOrders(request, SessionKey);
                            }
                            catch { }
                            return new PageList<PurchaseOrder>();
                        },
                        SavePurchaseOrderWithoutTradeIntoTrade
                        );

                }
            }
            catch (Exception e)
            {
                HandleException("更新分销流水号信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        private bool SavePurchaseOrderWithoutTradeIntoTrade(PurchaseOrder purchaseOrder)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.Trade dTrade = (from t in entities.Trade
                                          where t.tid == purchaseOrder.ID
                                          && t.Shop.ShopId == ShopID
                                          select t).FirstOrDefault();
                    bool addRecord = dTrade == null;
                    if (dTrade == null)
                    {
                        dTrade = new Model.Trade();
                        dTrade.tid = purchaseOrder.ID;
                        CopyPurchaseOrderToDbTrade(purchaseOrder, dTrade, GetShop(entities, ShopID));
                    }                

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToTrade(dTrade);
                        entities.SaveChanges();
                        message.AppendFormat("获取新的分销流水号信息：{0}", purchaseOrder.ID);
                    }
                    else
                    {
                        message.AppendFormat("分销流水号信息：{0}已经存在！", purchaseOrder.ID);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新分销交易:" + purchaseOrder.ID + "到数据库异常.", e,true);
            }
            return false;
        }
        #endregion

        #region Save to DataBase

        protected void SaveTradesDeliveries()
        {
            long total = 0, success = 0; 
            ExcuteUpdateStatus("开始更新需要发货的分销交易的物流信息...");
            try
            {
                List<long> allUnsentTradeIDs = new List<long>();
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    allUnsentTradeIDs = (from t in entities.Trade
                                                         where t.Shop.ShopId == ShopID 
                                                          && t.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                                         select t.tid).ToList();
                    total = allUnsentTradeIDs.Count;
                    OutputWriter.WriteLine("开始对分销交易做发货处理...", OutputFormatType.Title);
                }

                foreach (long tradeid in allUnsentTradeIDs)
                {
                    success += SaveTradeDelivery(tradeid) ? 1 : 0;
                }
            }
            catch (Exception e)
            {
                HandleException("更新将要发货的分销交易记录异常！", e);
            }
            OutputWriter.WriteLine("结束更新需要发货的分销交易的物流信息,一共需要更新" + total+"条，成功更新"+success+"条。", OutputFormatType.Title);
            OutputWriter.WriteLine("");
        }

        protected bool SaveTradeDelivery(long tid)
        {
            using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
            {
                Model.Trade trade = (from t in entities.Trade where t.tid == tid select t).FirstOrDefault();
                if (trade == null)
                    return false;

                try
                {
                    Model.FenXiaoDeliveryCache deliveryCache = (from d in entities.FenXiaoDeliveryCache
                                                                where d.Trade != null
                                                                && d.Trade.tid == trade.tid
                                                                && d.Shop != null
                                                                && d.Shop.ShopId == ShopID
                                                                select d).FirstOrDefault();
                    bool addRecord = deliveryCache == null;
                    if (addRecord)
                    {
                        deliveryCache = new Model.FenXiaoDeliveryCache();
                    }
                    deliveryCache.Shop = GetShop(entities,ShopID);
                    try
                    {
                        if (!IsNonRealTrade(trade))
                        {
                            //Confirm the trade is waiting seller send goods.
                            TradeFullinfoGetRequest tradeRequest = new TradeFullinfoGetRequest();
                            tradeRequest.Tid = trade.tid;
                            tradeRequest.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, num_iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                            Trade tTrade = Client.TradeFullinfoGet(tradeRequest, SessionKey);
                            if (tTrade.Status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                            {
                                // Has been Sent In other place.
                                //SaveTrade(tTrade, false);
                                trade.status = tTrade.Status;

                                var allPOrders = (from o in entities.PurchaseOrder
                                                  where o.Shop.ShopId == ShopID
                                                  && o.id == trade.tid
                                                  select o).ToList();
                                allPOrders.ForEach(o =>
                                {
                                    o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    o.SubPurchaseOrder.Load();
                                    foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                    {
                                        subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    }
                                });
                                //entities.SaveChanges();
                            }
                        }
                    }
                    catch (Exception te)
                    { }

                    deliveryCache.Trade = (from t in entities.Trade
                                           where t.tid == trade.tid
                                           && t.Shop.ShopId == ShopID
                                           select t).FirstOrDefault();
                    if (deliveryCache.Trade != null && deliveryCache.Trade.status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                    {
                        deliveryCache.IsSucess = true;
                        deliveryCache.Status = Constants.Delivery_Completed;
                    }

                    string deliveryMsg = String.Empty;
                    if (trade.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                    {
                        deliveryCache.IsSucess = false;
                        deliveryCache.Status = Constants.Delivery_Waiting;
                        deliveryMsg = "等待发货";
                    }
                    else if (trade.status == Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS
                        || trade.status == Constants.PurchaseOrder_TRADE_FINISHED)
                    {
                        deliveryCache.IsSucess = true;
                        deliveryCache.Status = Constants.Delivery_Completed;
                        deliveryMsg = "已在其他地方完成发货";
                    }
                    else
                    {
                        deliveryCache.IsSucess = false;
                        deliveryCache.Status = Constants.Delivery_UnKnown;
                        deliveryMsg = "未知";
                    }


                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToFenXiaoDeliveryCache(deliveryCache);
                        entities.SaveChanges();
                        message.AppendFormat("添加分销交易:{0}的物流信息,{1}.", trade.tid, deliveryMsg);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新分销交易:{0}的物流信息,{1}.", trade.tid, deliveryMsg);
                    }

                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                }
                catch (Exception error)
                {
                    HandleException("更新将要发货的分销交易记录：" + trade.tid + "失败！", error);
                }
                return true;
            } 
        }


        /// <summary>
        /// Check all the purchase order's status in the database, to collect the needed delivery ones.
        /// </summary>
        protected void SavePurchaseOrdersDeliveries()
        {
            ExcuteUpdateStatus("正在更新需要发货的采购单信息");
            try
            {
                OutputWriter.WriteLine("开始更新需要发货的分销采购单的物流信息...", OutputFormatType.Title);

                var allOrderIds = new List<long>();
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    allOrderIds = (from o in entities.PurchaseOrder
                                   where o.Shop.ShopId == ShopID
                                   && o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                   select o.id).ToList();
                }
                foreach (long orderId in allOrderIds)
                {
                    SavePurchaseOrderDelivery(orderId);
                }
            }
            catch (Exception e)
            {
                HandleException("更新需要发货的分销采购单的物流信息异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新需要发货的分销采购单的物流信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        protected bool SavePurchaseOrderDelivery(long pid)
        {
            using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
            {
                Model.PurchaseOrder order = (from o in entities.PurchaseOrder where o.id == pid select o).FirstOrDefault();
                if (order == null)
                    return false;

                try
                {
                    var delivery = (from d in entities.FenXiaoDeliveryCache
                                    where d.Trade != null && d.Trade.tid == pid
                                    && d.Shop.ShopId == ShopID
                                    select d).FirstOrDefault();

                    var addRecord = delivery == null;
                    if (addRecord)
                    {
                        delivery = new Model.FenXiaoDeliveryCache();
                    }

                    #region Set Trade
                    try
                    {
                        //TradeFullinfoGetRequest tradeRequest = new TradeFullinfoGetRequest();
                        //tradeRequest.Tid = pid;
                        //tradeRequest.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, num_iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                        //Trade tTrade = Client.TradeFullinfoGet(tradeRequest,SessionKey);
                        //if (SaveTrade(tTrade, false))
                        {
                            delivery.Trade = (from t in entities.Trade
                                              where t.tid == pid
                                              && t.Shop.ShopId == ShopID
                                              select t).FirstOrDefault();
                        }
                    }
                    catch (Exception te)
                    {
                    }

                    //Confirm the trade is from the TAOBAO, and If it's status is not “wait_seller_send_goods”,
                    //We should not add the trade to the unsent delivery table, and shou change the PurchaseOrder's status
                    if (delivery.Trade != null && delivery.Trade.status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                    {
                        order.status = delivery.Trade.status;
                        delivery.IsSucess = true;
                        delivery.Status = Constants.Delivery_Completed;
                    }
                    #endregion

                    string deliveryMsg = String.Empty;
                    if (order.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                    {
                        delivery.IsSucess = false;
                        delivery.Shop = GetShop(entities,ShopID);
                        delivery.Status = Constants.Delivery_Waiting;
                        deliveryMsg = "等待发货";
                    }
                    else if (order.status == Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS
                        || order.status == Constants.PurchaseOrder_TRADE_FINISHED)
                    {
                        deliveryMsg = "已在其他地方完成发货";
                    }
                    else
                    {
                        delivery.Status = Constants.Delivery_UnKnown;
                        deliveryMsg = "未知";
                    }

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToFenXiaoDeliveryCache(delivery);
                        entities.SaveChanges();
                        message.AppendFormat("添加分销采购单:{0}的物流信息,{1}.", pid, deliveryMsg);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新分销采购单:{0}的物流信息,{1}.", pid, deliveryMsg);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                }
                catch (Exception ep)
                {
                    HandleException("更新分销采购单:" + pid + "的物流信息失败.", ep);
                }
                return true;
            }
        }

        /// <summary>
        /// Send the purchase order which need the seller to send product.
        /// </summary>
        protected void SendDeliveries()
        {
            ExcuteUpdateStatus("正在发货...");
            int totalCount = 0;
            int succeedCount = 0;
            try
            {
                OutputWriter.WriteLine("开始处理采购单发货...", OutputFormatType.Title);

                var allOrderDeliveriyIds = new List<long>();
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    allOrderDeliveriyIds = (from d in entities.FenXiaoDelivery
                                            where (d.Status == Constants.Delivery_Waiting || d.Status == Constants.Delivery_Failed)
                                            && d.Shop.ShopId == ShopID
                                            && d.Trade != null
                                            //&& d.Trade.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                            && ((d.OrderType == Constants.OrderType_Delivery_Needed && !String.IsNullOrEmpty(d.OutSID))
                                                  || (d.OrderType == Constants.OrderType_Virtual_Goods))
                                            select d.ID).ToList();
                }

                totalCount = allOrderDeliveriyIds.Count;
                LogstatisticsStart("采购单发货", totalCount);

                foreach (long deliveryId in allOrderDeliveriyIds)
                {
                    succeedCount += SendDelivery(deliveryId) ? 1 : 0;
                }
            }
            catch (Exception e)
            {
                HandleException("处理采购单发货异常终止！", e);
            }
            finally
            {
                LogstatisticsEnd("采购单发货", totalCount, succeedCount);
            }
        }

        protected bool SendDelivery(long deliveryId)
        {
            using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
            {
                Model.FenXiaoDeliveryCache deliveryCache = null;
                Model.FenXiaoDelivery delivery = (from dl in entities.FenXiaoDelivery where dl.ID == deliveryId select dl).FirstOrDefault();
                if (delivery == null)
                    return false;

                try
                {
                    delivery.TradeReference.Load();
                    delivery.ShopReference.Load();
                    deliveryCache = (from dc in entities.FenXiaoDeliveryCache
                                     where dc.Trade != null && dc.Shop.ShopId == ShopID
                                     && dc.Trade.tid == delivery.Trade.tid
                                     select dc).FirstOrDefault();
                    bool needAddCache = deliveryCache == null;

                    try
                    {
                        if (needAddCache)
                        {
                            deliveryCache = new Model.FenXiaoDeliveryCache();
                        }
                        deliveryCache.CompanyCode = delivery.CompanyCode;
                        deliveryCache.IsSucess = delivery.IsSucess;
                        deliveryCache.Memo = delivery.Memo;
                        deliveryCache.OrderType = delivery.OrderType;
                        deliveryCache.OutSID = delivery.OutSID;
                        deliveryCache.Shop = delivery.Shop;
                        deliveryCache.Status = delivery.Status;
                        deliveryCache.Trade = delivery.Trade;
                        if (needAddCache)
                        {
                            entities.AddToFenXiaoDeliveryCache(deliveryCache);
                        }
                        entities.SaveChanges();
                    }
                    catch (Exception e)
                    {
                        HandleException(e.Message, e);
                        return false;
                    }

                    if (delivery.Trade.status == Constants.PurchaseOrder_TRADE_CLOSED
                        || delivery.Trade.status == Constants.PurchaseOrder_TRADE_CLOSED_BY_TAOBAO)
                    {
                        entities.SaveChanges();
                        return true ;
                    }

                    bool hasSent = false;
                    bool needSend = false;
                    try
                    {
                        deliveryCache.TradeReference.Load();
                        if (!IsNonRealTrade(deliveryCache.Trade))
                        {
                            TradeGetRequest tradeGetRequest = new TradeGetRequest();
                            tradeGetRequest.Tid = deliveryCache.Trade.tid;
                            tradeGetRequest.Fields = "tid, status, payment,consign_time";
                            Trade realTrade = Client.TradeGet(tradeGetRequest, SessionKey);
                            hasSent = (realTrade.Status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                         && !String.IsNullOrEmpty(realTrade.ConsignTime))
                                         || (realTrade.Status == Constants.PurchaseOrder_TRADE_CLOSED)
                                         || (realTrade.Status == Constants.PurchaseOrder_TRADE_FINISHED)
                                         || (realTrade.Status == Constants.PurchaseOrder_TRADE_CLOSED_BY_TAOBAO);
                        }
                        else
                        {
                             FenXiaoGetOrdersRequest purchaseOrdersGetRequest = new FenXiaoGetOrdersRequest();
                             purchaseOrdersGetRequest.PurchaseOrderID = deliveryCache.Trade.tid;
                            PageList<PurchaseOrder> purchaseOrders = Client.FenXiaoGetOrders(purchaseOrdersGetRequest, SessionKey);
                            if (purchaseOrders.Content.Count > 0)
                            {
                                var tPOder = purchaseOrders.Content[0];
                                hasSent = (tPOder.Status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                        && !String.IsNullOrEmpty(tPOder.ConSignTime))
                                        || (tPOder.Status == Constants.PurchaseOrder_TRADE_CLOSED)
                                        || (tPOder.Status == Constants.PurchaseOrder_TRADE_FINISHED)
                                        || (tPOder.Status == Constants.PurchaseOrder_TRADE_CLOSED_BY_TAOBAO);
                            }
                        }
                        #region Has been Sent in other place
                        if (hasSent)
                        {
                            OutputWriter.WriteLine("采购单:" + deliveryCache.Trade.tid + " 以在其他地方发货。", OutputFormatType.Success);
                            deliveryCache.Status = Constants.Delivery_Completed;
                            deliveryCache.IsSucess = true;
                            entities.SaveChanges();
                            //Update Trade && PurchaseOrder 
                            try
                            {
                                deliveryCache.TradeReference.Load();
                                deliveryCache.Trade.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;

                                List<Model.PurchaseOrder> purchaseOrders = (from o in entities.PurchaseOrder
                                                                            where o.Trade.tid == deliveryCache.Trade.tid
                                                                            && o.Shop.ShopId == ShopID
                                                                            select o).ToList();
                                purchaseOrders.ForEach(o =>
                                {
                                    o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    o.SubPurchaseOrder.Load();
                                    foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                    {
                                        subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    }
                                });
                                entities.SaveChanges();
                                OutputWriter.WriteLine("交易:" + deliveryCache.Trade.tid + " 和相应的分销采购单的状态更新成功。", OutputFormatType.Success);
                            }
                            catch (Exception error)
                            {
                                HandleException("交易:" + deliveryCache.Trade.tid + " 和相应的分销采购单的状态更新异常。", error);
                            }
                            entities.SaveChanges();
                            return true;
                        }
                        #endregion

                    }
                    catch (Exception te)
                    {
                        return false;
                    }

                    if (hasSent)
                        return true;

                    #region Need Delivery

                    DeliverySendRequest request = new DeliverySendRequest();
                    request.Tid = deliveryCache.Trade.tid;
                    if (deliveryCache.OrderType != Constants.OrderType_Virtual_Goods)
                    {
                        Model.Sender sender = (from s in entities.Sender
                                               where s.Shop == ShopID
                                               select s).FirstOrDefault();
                        if (sender == null)
                        {
                            HandleException("采购单：" + deliveryCache.Trade.tid + " 发货失败，没有当前店铺:" + ShopName + "的发送者信息！", new Exception("没有当前店铺:" + ShopID + "的发送者信息！"));
                            entities.SaveChanges();
                            return false;
                        }

                        if (String.IsNullOrEmpty(deliveryCache.CompanyCode))
                        {
                            request.CompanyCode = sender.CompanyCode;
                        }
                        else
                        {
                            request.CompanyCode = deliveryCache.CompanyCode;
                        }
                        request.Memo = String.IsNullOrEmpty(deliveryCache.Memo) ? "Thanks," : deliveryCache.Memo;
                        request.OutSid = deliveryCache.OutSID;
                        request.SellerAddress = sender.Address;
                        request.SellerAreaId = sender.AreaID;
                        request.SellerMobile = sender.Mobile;
                        request.SellerName = sender.Name;
                        request.SellerPhone = sender.Phone;
                        request.SellerZip = sender.Zip;

                    }
                    else
                    {
                        request.OrderType = deliveryCache.OrderType;
                    }

                    Shipping shipping = Client.DeliverySend(request, SessionKey);
                    if (shipping.IsSuccess)
                    {
                        OutputWriter.WriteLine("采购单：" + " 发货成功。", OutputFormatType.Success);
                        deliveryCache.Status = Constants.Delivery_Completed;
                        deliveryCache.IsSucess = true;
                        entities.SaveChanges();

                        //Update Trade && PurchaseOrder 
                        try
                        {
                            deliveryCache.TradeReference.Load();
                            deliveryCache.Trade.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;

                            List<Model.PurchaseOrder> purchaseOrders = (from o in entities.PurchaseOrder
                                                                        where o.Trade.tid == deliveryCache.Trade.tid
                                                                        && o.Shop.ShopId == ShopID
                                                                        select o).ToList();
                            purchaseOrders.ForEach(o =>
                            {
                                o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                o.SubPurchaseOrder.Load();
                                foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                {
                                    subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                }
                            });
                            entities.SaveChanges();
                            OutputWriter.WriteLine("交易:" + deliveryCache.Trade.tid + " 和相应的分销采购单的状态更新成功。", OutputFormatType.Success);
                        }
                        catch (Exception error)
                        {
                            HandleException("交易:" + deliveryCache.Trade.tid + " 和相应的分销采购单的状态更新异常。", error);
                        }
                    }
                    else
                    {
                        OutputWriter.WriteLine("采购单：" + deliveryCache.Trade.tid + " 发货失败。", OutputFormatType.Failed);
                        deliveryCache.Shop = GetShop(entities, ShopID);
                        deliveryCache.Status = Constants.Delivery_Failed;
                        deliveryCache.IsSucess = false;
                        entities.SaveChanges();
                    }
                    #endregion

                }
                catch (Exception e)
                {
                    try
                    {
                        if (deliveryCache != null)//将所有发货未成功的订单状态都改为失败。
                        {
                            deliveryCache.Shop = GetShop(entities, ShopID);
                            deliveryCache.Status = Constants.Delivery_Failed;
                            deliveryCache.IsSucess = false;
                            entities.SaveChanges();
                        }
                    }
                    catch { }
                    HandleException("采购单：" + delivery.Trade.tid + " 发货失败。", e);
                }
                finally
                {
                    entities.SaveChanges();
                }
                return true;
            }
        }

        /// <summary>
        /// Save the Refund to the DataBase, from the refund information of TAOBAO
        /// </summary>
        /// <param name="tRefund">the Refund information of TAOBAO</param>
        /// <returns></returns>
        protected bool SaveRefund(Refund tRefund)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.Refund dRefund = (from r in entities.Refund
                                            where r.RefundID == tRefund.RefundId
                                            && r.Shop.ShopId == ShopID
                                            select r).FirstOrDefault();
                    bool addRecord = dRefund == null;
                    if (addRecord)
                    {
                        dRefund = new Model.Refund();
                        dRefund.RefundID = tRefund.RefundId;
                        dRefund.Shop = GetShop(entities,ShopID);
                    }

                    dRefund.address = tRefund.Address;
                    dRefund.alipay_no = tRefund.AlipayNo;
                    dRefund.buyer_nick = tRefund.BuyerNick;
                    dRefund.company_name = tRefund.CompanyName;
                    if (!String.IsNullOrEmpty(tRefund.Created))
                        dRefund.created = Convert.ToDateTime(tRefund.Created);
                    dRefund.desc = tRefund.Desc;
                    if (!String.IsNullOrEmpty(tRefund.GoodReturnTime))
                        dRefund.good_return_time = Convert.ToDateTime(tRefund.GoodReturnTime);
                    dRefund.good_status = tRefund.GoodStatus;
                    dRefund.has_good_return = tRefund.HasGoodReturn;
                    dRefund.iid = tRefund.Iid;
                    if (!String.IsNullOrEmpty(tRefund.Modified))
                        dRefund.modified = Convert.ToDateTime(tRefund.Modified);
                    dRefund.num = tRefund.Num;
                    dRefund.num_iid = tRefund.NumIid;
                    dRefund.order_status = tRefund.OrderStatus; ;
                    dRefund.payment = tRefund.Payment;
                    dRefund.price = tRefund.Price;
                    dRefund.reason = tRefund.Reason;
                    dRefund.refund_fee = tRefund.RefundFee;
                    dRefund.seller_nick = tRefund.SellerNick;
                    dRefund.shipping_type = tRefund.ShippingType;
                    dRefund.sid = tRefund.Sid;
                    dRefund.status = tRefund.Status;
                    dRefund.title = tRefund.Title;
                    dRefund.total_fee = tRefund.TotalFee;

                    //Trade
                    dRefund.tid = tRefund.Tid;

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToRefund(dRefund);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的退款采购单:{0}.", tRefund.RefundId);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新退款采购单:{0}.", tRefund.RefundId);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新退款单:" + tRefund.RefundId + "的信息到数据库失败！", e);
            }
            return false;
        }

        /// <summary>
        /// Save the purchase order to the Database, from the order information of TAOBAO
        /// </summary>
        /// <param name="tOrder">the order information from TAOBAO</param>
        /// <returns></returns>
        protected bool SavePurchaseOrder(PurchaseOrder tOrder, bool displayMessage)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.PurchaseOrder dOrder = (from o in entities.PurchaseOrder
                                                  where o.id == tOrder.ID
                                                  && o.Shop.ShopId == ShopID
                                                  select o).FirstOrDefault();
                    bool addRecord = dOrder == null;
                    if (addRecord)
                    {
                        dOrder = new Model.PurchaseOrder();
                        dOrder.id = tOrder.ID;
                    }
                    var alipay_no = 0L;
                    if (Int64.TryParse(tOrder.AlipayNo,out alipay_no) && alipay_no > 0)
                    {
                        dOrder.alipay_no = alipay_no;
                    }
                    dOrder.buyer_nick = tOrder.BuyerNick;
                    if (!String.IsNullOrEmpty(tOrder.ConSignTime))
                        dOrder.consign_time = Convert.ToDateTime(tOrder.ConSignTime);
                    if (!String.IsNullOrEmpty(tOrder.Created))
                        dOrder.created = Convert.ToDateTime(tOrder.Created);
                    dOrder.distributor_from = tOrder.DistributorFrom;
                    dOrder.distributor_memo = tOrder.Memo;
                    dOrder.distributor_payment = tOrder.DistributorPayment;
                    dOrder.distributor_username = tOrder.DistributorUserName;
                    //Set Distributor
                    string nicks = tOrder.DistributorUserName;

                    try
                    {
                        FenXiaoGetDistributorsRequest distrRequest = new FenXiaoGetDistributorsRequest();
                        distrRequest.Nicks = nicks;
                        PageList<Distributor> allDistributors = Client.FenXiaoGetDistributors(distrRequest, SessionKey);
                        if (allDistributors.Content.Count > 0)
                        {
                            Distributor td = allDistributors.Content[0];
                            Model.Distributor distributor = (from d in entities.Distributor
                                                             where d.distributor_id == td.DistributorID
                                                             && d.Shop.ShopId == ShopID
                                                             select d).FirstOrDefault();
                            if (distributor != null)
                            {
                                distributor.alipay_account = td.AlipayAccount;
                                distributor.contact_person = td.ContactPerson;
                                distributor.created = ConvertDateTime(td.Created); 
                                distributor.distributor_name = td.DistributorName;
                                distributor.email = td.Email;
                                distributor.mobile_phone = td.MobilePhone;
                                distributor.phone = td.Phone;
                                distributor.Shop = GetShop(entities, ShopID);
                                distributor.shop_web_link = td.ShopWebLink;
                                distributor.user_id = td.UserID;
                                entities.SaveChanges();
                            }
                            else
                            {
                                distributor = new Model.Distributor();
                                distributor.alipay_account = td.AlipayAccount;
                                distributor.contact_person = td.ContactPerson;
                                distributor.created = ConvertDateTime(td.Created);
                                distributor.distributor_id = td.DistributorID;
                                distributor.distributor_name = td.DistributorName;
                                distributor.email = td.Email;
                                distributor.mobile_phone = td.MobilePhone;
                                distributor.phone = td.Phone;
                                distributor.Shop = GetShop(entities, ShopID);
                                distributor.shop_web_link = td.ShopWebLink;
                                distributor.user_id = td.UserID;
                                entities.AddToDistributor(distributor);
                            }
                            dOrder.distributor_id = distributor.distributor_id;         
                        }
                    }
                    catch (Exception ep)
                    {
                    }


                    if (!String.IsNullOrEmpty(tOrder.Modified))
                        dOrder.modified = Convert.ToDateTime(tOrder.Modified);
                    if (!String.IsNullOrEmpty(tOrder.PayTime))
                        dOrder.pay_time = Convert.ToDateTime(tOrder.PayTime);
                    dOrder.post_fee = tOrder.PostFee;
                    dOrder.snapshot_url = tOrder.SnapShotUrl;
                    dOrder.status = tOrder.Status;
                    dOrder.supplier_from = tOrder.SupplierFrom;
                    dOrder.supplier_username = tOrder.SupplierFrom;
                    dOrder.total_fee = tOrder.TotalFee;
                    dOrder.type = tOrder.Type;

                    dOrder.Shop = GetShop(entities,ShopID);

                    dOrder.Trade = (from t in entities.Trade
                                    where t.tid == tOrder.ID
                                    && t.Shop.ShopId == ShopID
                                    select t).FirstOrDefault();

                    //Receiver 
                    Model.Receiver receiver = (from r in entities.Receiver
                                               where r.address == tOrder.Receiver.Address
                                                   && r.city == tOrder.Receiver.City
                                                   && r.district == tOrder.Receiver.District
                                                   && (r.mobile_phone == tOrder.Receiver.MobilePhone || (r.mobile_phone == null && tOrder.Receiver.MobilePhone == null))
                                                   && r.name == tOrder.Receiver.Name
                                                   && (r.phone == tOrder.Receiver.Phone||(r.phone==null && tOrder.Receiver.Phone==null))
                                                   && r.state == tOrder.Receiver.State
                                                   && r.zip == tOrder.Receiver.Zip
                                                   && r.shop == ShopID
                                               select r).FirstOrDefault();
                    if (receiver == null)
                    {
                        receiver = new Model.Receiver();
                        receiver.address = tOrder.Receiver.Address;
                        receiver.city = tOrder.Receiver.City;
                        receiver.district = tOrder.Receiver.District;
                        receiver.mobile_phone = tOrder.Receiver.MobilePhone;
                        receiver.name = tOrder.Receiver.Name;
                        receiver.phone = tOrder.Receiver.Phone;
                        receiver.state = tOrder.Receiver.State;
                        receiver.zip = tOrder.Receiver.Zip;
                        receiver.shop = ShopID;
                        entities.AddToReceiver(receiver);
                    }
                    dOrder.Receiver = receiver;

                    dOrder.SubPurchaseOrderCount = tOrder.SubPurchaseOrders.Count;

                    //TODO: Distributor Information

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToPurchaseOrder(dOrder);
                        entities.SaveChanges();
                        message.AppendFormat("获得分销采购单:{0}成功", tOrder.ID);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新分销采购单:{0}成功", tOrder.ID);
                    }
                    if (displayMessage)
                        OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新分销采购单:" + tOrder.ID + "的信息到数据库失败！", e, displayMessage);
            }
            return false;
        }

        /// <summary>
        /// Save the Sub Purchase Order to Database
        /// </summary>
        /// <param name="dOrder">The parent order in the Database, of the current suborder from TAOBAO</param>
        /// <param name="tSubOrder">The sub order from TAOBAO</param>
        /// <returns></returns>
        protected bool SaveSubPurchaseOrder(long dOrderID, SubPurchaseOrder tSubOrder, bool displayMessage)
        { 
            try
            {   
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.SubPurchaseOrder dSubOrder = null;
                    if (tSubOrder.ID > 0 && tSubOrder.FenXiaoID>0)
                    {
                        dSubOrder = (from o in entities.SubPurchaseOrder
                                     where (o.id == tSubOrder.ID || o.fenxiao_id==tSubOrder.FenXiaoID)
                                     && o.Shop.ShopId == ShopID
                                     select o).FirstOrDefault();
                    }
                    else if (tSubOrder.ID > 0)
                    {
                        dSubOrder = (from o in entities.SubPurchaseOrder
                                     where o.id == tSubOrder.ID
                                     && o.Shop.ShopId == ShopID
                                     select o).FirstOrDefault();
                    }
                    else
                    {
                        dSubOrder = (from o in entities.SubPurchaseOrder
                                     where o.fenxiao_id == tSubOrder.FenXiaoID
                                     && o.Shop.ShopId == ShopID
                                     select o).FirstOrDefault();
                    }
                    bool addRecord = dSubOrder == null;
                    if (addRecord)
                    {
                        dSubOrder = new Model.SubPurchaseOrder();
                        dSubOrder.id = tSubOrder.ID;
                        dSubOrder.fenxiao_id = tSubOrder.FenXiaoID;
                    }

                    dSubOrder.buyer_payment = tSubOrder.BuyerPayment;
                    if (!String.IsNullOrEmpty(tSubOrder.Created))
                        dSubOrder.created = Convert.ToDateTime(tSubOrder.Created);
                    dSubOrder.distributor_payment = tSubOrder.DistributorPayment;

                    //Item TODO
                    long pid = tSubOrder.ItemID;

                    Model.FenxiaoProduct mProduct = (from p in entities.FenxiaoProduct
                                                     where p.pid == pid
                                                     && p.Shop.ShopId == ShopID
                                                     select p).FirstOrDefault();
                    if (mProduct != null)
                    {
                        dSubOrder.FenxiaoProduct = mProduct;
                    }
                    else
                    {
                        try
                        {
                            FenXiaoGetProductsRequest pRequest = new FenXiaoGetProductsRequest();
                            pRequest.PID = pid.ToString();
                            PageList<FenxiaoProduct> products = Client.FenXiaoGetProducts(pRequest, SessionKey);
                            if (products.Content.Count > 0)
                            {
                                if (dSubOrder.FenxiaoProduct == null || dSubOrder.FenxiaoProduct.pid != pid)
                                {
                                    dSubOrder.FenxiaoProduct = new Model.FenxiaoProduct();
                                    dSubOrder.FenxiaoProduct.pid = pid;
                                }
                                FenxiaoProduct fp = products.Content[0];
                                dSubOrder.FenxiaoProduct.alarm_number = fp.AlertNumber;
                                dSubOrder.FenxiaoProduct.city = fp.City;
                                dSubOrder.FenxiaoProduct.cost_price = fp.CostPrice;
                                dSubOrder.FenxiaoProduct.created = ConvertDateTime(fp.Created);
                                dSubOrder.FenxiaoProduct.desc_path = fp.DescPath;
                                dSubOrder.FenxiaoProduct.have_guarantee = fp.HaveGuanrantee;
                                dSubOrder.FenxiaoProduct.have_invoice = fp.HaveInvoice;
                                dSubOrder.FenxiaoProduct.items_count = fp.ItemsCount;
                                dSubOrder.FenxiaoProduct.modified = ConvertDateTime(fp.Modified);
                                dSubOrder.FenxiaoProduct.name = fp.Name;
                                dSubOrder.FenxiaoProduct.orders_count = fp.OrdersCount;
                                dSubOrder.FenxiaoProduct.outer_id = fp.OuterID;
                                dSubOrder.FenxiaoProduct.pictures = fp.Pictures;
                                dSubOrder.FenxiaoProduct.postage_ems = fp.PostageEMS;
                                dSubOrder.FenxiaoProduct.postage_fast = fp.PostageFast;
                                dSubOrder.FenxiaoProduct.postage_id = fp.PostageID;
                                dSubOrder.FenxiaoProduct.postage_ordinary = fp.PostageOrdinary;
                                dSubOrder.FenxiaoProduct.postage_type = fp.PostageType;
                                dSubOrder.FenxiaoProduct.productcat_id = fp.ProductCatID;
                                dSubOrder.FenxiaoProduct.prov = fp.Province;
                                dSubOrder.FenxiaoProduct.quantity = fp.Quantity;
                                dSubOrder.FenxiaoProduct.retail_price_high = fp.RetailPriceHigh;
                                dSubOrder.FenxiaoProduct.retail_price_low = fp.RetailPriceLow;
                                dSubOrder.FenxiaoProduct.Shop = GetShop(entities,ShopID);
                                dSubOrder.FenxiaoProduct.standard_price = fp.StandardPrice;
                                dSubOrder.FenxiaoProduct.status = fp.Status;
                            }
                        }
                        catch (Exception perror)
                        {
                            HandleException("更新分销采购单:" + dOrderID + "的子采购单:" + tSubOrder.ID+"的产品信息异常", perror);
                        }
                    }

                    dSubOrder.item_outer_id = tSubOrder.ItemOuterID;

                    dSubOrder.num = tSubOrder.Num;
                    dSubOrder.price = tSubOrder.Price;
                    dSubOrder.sku_id = tSubOrder.SkuID;
                    dSubOrder.sku_outer_id = tSubOrder.SkuOuterID;
                    dSubOrder.sku_properties = tSubOrder.SkuProperties;
                    dSubOrder.snapshot_url = tSubOrder.SnapShotUrl;
                    dSubOrder.status = tSubOrder.Status;
                    dSubOrder.title = tSubOrder.Title;
                    dSubOrder.total_fee = tSubOrder.TotalFee;

                    dSubOrder.PurchaseOrder = (from o in entities.PurchaseOrder
                                               where o.id == dOrderID
                                               select o).FirstOrDefault();
                    dSubOrder.Shop = GetShop(entities,ShopID);

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToSubPurchaseOrder(dSubOrder);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的分销采购单:{0}的子采购单:{1}.", dOrderID, tSubOrder.ID);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新分销采购单:{0}的子采购单:{1}.", dOrderID, tSubOrder.ID);
                    }
                    if (displayMessage)
                        OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新分销采购单:" + dOrderID + "的子采购单:" + tSubOrder.ID + "到数据库失败！", e, displayMessage);
            }
            return false;
        }

        /// <summary>
        /// Save the Distributor's information to the Database
        /// </summary>
        /// <param name="tDistributor">The Distributor's information Get from TAOBAO</param>
        /// <returns></returns>
        protected bool SaveDistributor(Distributor tDistributor)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.Distributor dDistributor = (from d in entities.Distributor
                                                      where d.distributor_id == tDistributor.DistributorID
                                                      && d.Shop.ShopId == ShopID
                                                      select d).FirstOrDefault();
                    bool addRecord = (dDistributor == null);
                    if (addRecord)
                    {
                        dDistributor = new Model.Distributor();
                        dDistributor.distributor_id = tDistributor.DistributorID;
                    }
                    dDistributor.alipay_account = tDistributor.AlipayAccount;
                    dDistributor.contact_person = tDistributor.ContactPerson;
                    //if (!String.IsNullOrEmpty(tDistributor.Created))
                    //    dDistributor.created = Convert.ToDateTime(tDistributor.Created); 
                    dDistributor.distributor_name = tDistributor.DistributorName;
                    dDistributor.email = tDistributor.Email;
                    //dDistributor.mobile_phone = tDistributor.MobilePhone;
                    dDistributor.phone = tDistributor.Phone;
                    dDistributor.shop_web_link = tDistributor.ShopWebLink;
                    //dDistributor.user_id = tDistributor.UserID;
                    dDistributor.Shop = GetShop(entities,ShopID);

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToDistributor(dDistributor);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的分销商信息:{0}.", tDistributor.DistributorID);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新分销商信息:{0}.", tDistributor.DistributorID);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新分销商信息:" + tDistributor.DistributorID + "的信息到数据库失败！", e);
            }
            return false; 
        }


        protected bool SaveProductCat(ProductCat tProductCat)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    var dProductCat = (from pc in entities.ProductCat
                                       where pc.id == tProductCat.ID
                                       && pc.Shop.ShopId == ShopID
                                       select pc).FirstOrDefault();
                    bool addRecord = dProductCat == null;
                    if (addRecord)
                    {
                        dProductCat = new Model.ProductCat();
                        dProductCat.id = tProductCat.ID;
                    }
                    dProductCat.Shop = GetShop(entities,ShopID);
                    dProductCat.product_num = tProductCat.ProductNum;
                    dProductCat.name = tProductCat.Name;

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToProductCat(dProductCat);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的产品线:{0}.", tProductCat.ID);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新产品线:{0}.", tProductCat.ID);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新产品线:" + tProductCat.ID + "的信息到数据库失败！", e);
            }
            return false;
        }

        protected bool SaveFenXiaoProduct(FenxiaoProduct tProduct)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    var dProduct = (from p in entities.FenxiaoProduct
                                    where p.pid == tProduct.PID
                                    && p.Shop.ShopId == ShopID
                                    select p
                                        ).FirstOrDefault();

                    bool addRecord = dProduct == null;

                    if (addRecord)
                    {
                        dProduct = new Model.FenxiaoProduct();
                        dProduct.pid = tProduct.PID;
                    }
                    dProduct.Shop = GetShop(entities,ShopID);
                    dProduct.alarm_number = tProduct.AlertNumber;
                    dProduct.city = tProduct.City;
                    dProduct.cost_price = tProduct.CostPrice;
                    if (!String.IsNullOrEmpty(tProduct.Created))
                        dProduct.created = Convert.ToDateTime(tProduct.Created);
                    dProduct.desc_path = tProduct.DescPath;
                    dProduct.have_guarantee = tProduct.HaveGuanrantee;
                    dProduct.have_invoice = tProduct.HaveInvoice;
                    dProduct.items_count = tProduct.ItemsCount;
                    if (!String.IsNullOrEmpty(tProduct.Modified))
                        dProduct.created = Convert.ToDateTime(tProduct.Modified);
                    dProduct.name = tProduct.Name;
                    dProduct.orders_count = tProduct.OrdersCount;
                    dProduct.outer_id = tProduct.OuterID;
                    dProduct.pictures = tProduct.Pictures;
                    dProduct.postage_ems = tProduct.PostageEMS;
                    dProduct.postage_fast = tProduct.PostageFast;
                    dProduct.postage_id = tProduct.PostageID;
                    dProduct.postage_ordinary = tProduct.PostageOrdinary;
                    dProduct.postage_type = tProduct.PostageType;
                    dProduct.productcat_id = tProduct.ProductCatID;
                    dProduct.prov = tProduct.Province;
                    dProduct.quantity = tProduct.Quantity;
                    dProduct.retail_price_high = tProduct.RetailPriceHigh;
                    dProduct.retail_price_low = tProduct.RetailPriceLow;
                    dProduct.standard_price = tProduct.StandardPrice;
                    dProduct.status = tProduct.Status;

                    //Skus
                    dProduct.FenXiaoProduct_Sku = new System.Data.Objects.DataClasses.EntityCollection<Model.FenXiaoProduct_Sku>();
                    foreach (FenxiaoSku sku in tProduct.Skus)
                    {
                        var dPSkuRelation = new Model.FenXiaoProduct_Sku();
                        dPSkuRelation.Shop = GetShop(entities,ShopID);
                        dPSkuRelation.FenxiaoProduct = dProduct;
                        Model.FenxiaoSku dSku = (from s in entities.FenxiaoSku
                                                 where s.id == sku.ID
                                                 && s.Shop.ShopId == ShopID
                                                 select s).FirstOrDefault();
                        if (dSku == null)
                        {
                            dSku = new Model.FenxiaoSku();
                            dSku.id = sku.ID;
                        }
                        dSku.cost_price = sku.CostPrice;
                        dSku.name = sku.Name;
                        dSku.outer_id = sku.OuterID;
                        dSku.quantity = sku.Quantity;
                        dSku.Shop = GetShop(entities,ShopID);
                        dPSkuRelation.FenxiaoSku = dSku;
                        dProduct.FenXiaoProduct_Sku.Add(dPSkuRelation);
                    }

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToFenxiaoProduct(dProduct);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的产品:{0}.", tProduct.PID);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新产品信息:{0}.", tProduct.PID);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新产品信息:" + tProduct.PID + " 到数据库失败！", e);
            }
            return false;
        }

        protected bool SaveTrade(Trade tTrade, bool displayMessage)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.Trade dTrade = (from t in entities.Trade
                                          where t.tid == tTrade.Tid
                                          && t.Shop.ShopId == ShopID
                                          select t).FirstOrDefault();
                    bool addRecord = dTrade == null;
                    if (addRecord)
                    {
                        dTrade = new Model.Trade();
                        dTrade.tid = tTrade.Tid;
                    }
                    dTrade.Shop = GetShop(entities,ShopID);
                    dTrade.adjust_fee = tTrade.AdjustFee;
                    dTrade.alipay_no = tTrade.AlipayNo;
                    dTrade.available_confirm_fee = tTrade.AvailableConfirmFee;
                    dTrade.buyer_alipay_no = tTrade.BuyerAlipayNo;
                    dTrade.buyer_email = tTrade.BuyerEmail;
                    dTrade.buyer_flag = tTrade.BuyerFlag;
                    dTrade.buyer_memo = tTrade.BuyerMemo;
                    dTrade.buyer_message = tTrade.BuyerMessage;
                    dTrade.buyer_nick = tTrade.BuyerNick;
                    dTrade.buyer_obtain_point_fee = tTrade.BuyerObtainPointFee;
                    dTrade.buyer_rate = tTrade.BuyerRate;
                    dTrade.cod_fee = tTrade.CodFee;
                    dTrade.cod_status = tTrade.CodStatus;
                    dTrade.commission_fee = tTrade.CommissionFee;
                    dTrade.consign_time = ConvertDateTime(tTrade.ConsignTime);
                    dTrade.created = ConvertDateTime(tTrade.Created);
                    dTrade.discount_fee = tTrade.DiscountFee;
                    dTrade.end_time = ConvertDateTime(tTrade.EndTime);
                    dTrade.has_post_fee = tTrade.HasPostFee;
                    dTrade.iid = tTrade.Iid;
                    dTrade.invoice_name = tTrade.InvoiceName;
                    dTrade.is_3D = tTrade.Is3D;
                    dTrade.modified = ConvertDateTime(tTrade.Modified);
                    dTrade.num = tTrade.Num;
                    dTrade.num_iid = tTrade.NumIid;
                    dTrade.payment = tTrade.Payment;
                    dTrade.pay_time = ConvertDateTime(tTrade.PayTime);
                    dTrade.pic_path = tTrade.PicPath;
                    dTrade.point_fee = tTrade.PointFee;
                    dTrade.post_fee = tTrade.PostFee;
                    dTrade.price = tTrade.Price;
                    dTrade.promotion = tTrade.Promotion;
                    dTrade.real_point_fee = tTrade.RealPointFee;
                    dTrade.received_payment = tTrade.ReceivedPayment;
                    dTrade.receiver_address = tTrade.ReceiverAddress;
                    dTrade.receiver_city = tTrade.ReceiverCity;
                    dTrade.receiver_district = tTrade.ReceiverDistrict;
                    dTrade.receiver_mobile = tTrade.ReceiverMobile;
                    dTrade.receiver_name = tTrade.ReceiverName;
                    dTrade.receiver_phone = tTrade.ReceiverPhone;
                    dTrade.receiver_state = tTrade.ReceiverState;
                    dTrade.receiver_zip = tTrade.ReceiverZip;
                    dTrade.seller_alipay_no = tTrade.SellerAlipayNo;
                    dTrade.seller_email = tTrade.SellerEmail;
                    dTrade.seller_flag = tTrade.SellerFlag;
                    dTrade.seller_memo = tTrade.SellerMemo;
                    dTrade.seller_mobile = tTrade.SellerMobile;
                    dTrade.seller_name = tTrade.SellerName;
                    dTrade.seller_nick = tTrade.SellerNick;
                    dTrade.seller_phone = tTrade.SellerPhone;
                    dTrade.seller_rate = tTrade.SellerRate;
                    dTrade.shipping_type = tTrade.ShippingType;
                    dTrade.snapshot = tTrade.Snapshot;
                    dTrade.snapshot_url = tTrade.SnapshotUrl;
                    dTrade.status = tTrade.Status;
                    dTrade.timeout_action_time = ConvertDateTime(tTrade.TimeoutActionTime);
                    dTrade.title = tTrade.Title;
                    dTrade.total_fee = tTrade.TotalFee;
                    dTrade.trade_memo = tTrade.TradeMemo;
                    dTrade.type = tTrade.Type;
                    dTrade.sid = tTrade.Sid;

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToTrade(dTrade);
                        entities.SaveChanges();
                        message.AppendFormat("获取新的交易信息：{0}", tTrade.Tid);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新交易信息：{0}", tTrade.Tid);
                    }
                    if (displayMessage)
                        OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException("更新分销交易:" + tTrade.Tid + "到数据库异常.", e, displayMessage);
            }
            return false;
        }

        protected bool SaveFullTrade(Trade tTrade)
        {
            if (SaveTrade(tTrade, true))
            {
                try
                {
                    TradeFullinfoGetRequest request = new TradeFullinfoGetRequest();
                    request.Tid = tTrade.Tid;
                    request.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, num_iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                    Trade fullTTrade = Client.TradeFullinfoGet(request, SessionKey);
                    SaveTrade(fullTTrade, false);
                    OutputWriter.WriteLine("更新分销交易：" + tTrade.Tid + "的详细信息成功！", OutputFormatType.Success);
                    return true;
                }
                catch (Exception e)
                {
                    HandleException("更新分销交易：" + tTrade.Tid + "的详细信息异常.", e);
                }
            }
            return false;
        }

        #endregion

        #region Assist Method

        protected int ProcessPageList<T>(string contentName, int pageSize, PageList<T> firstContentList, Func<int, PageList<T>> getNextContentList, Func<T, bool> processAction)
            where T : BaseObject
        {
            return ProcessPageList<T>(contentName, pageSize, firstContentList, getNextContentList, processAction,firstContentList.TotalResults);
        }

        protected int ProcessPageList<T>(string contentName, int pageSize, PageList<T> firstContentList, Func<int, PageList<T>> getNextContentList, Func<T, bool> processAction, long totalCount)
           where T : BaseObject
        {
            int success = 0;
            int pageCount = (int)(totalCount / pageSize) + ((totalCount % pageSize > 0) ? 1 : 0);
            OutputWriter.WriteLine("将要获取的" + contentName + "的总页数为:" + pageCount + "页，每页:" + pageSize + "条。", OutputFormatType.Title);
            int currentPageNo = 1;
            PageList<T> currentContentList = firstContentList;
            do
            {
                try
                {
                    OutputWriter.WriteLine("第" + currentPageNo + "页：", OutputFormatType.Title);
                    foreach (T t in currentContentList.Content)
                    {
                        if (processAction(t))
                            success++;
                    }
                }
                catch (Exception e)
                {
                    HandleException("更新第" + currentPageNo + "页的" + contentName + "失败。", e);
                    Thread.Sleep(1000);
                }
                currentPageNo++;
                currentContentList = getNextContentList(currentPageNo);
            } while (currentPageNo <= pageCount);
            return success;
        }
        #endregion

        #region Update Product Information From TAOBAO

        protected void UpdateProducts()
        {
            ExcuteUpdateStatus("正在更新产品信息");

            try
            {
                OutputWriter.WriteLine("开始更新产品信息...", OutputFormatType.Title);
                FenXiaoGetProductsRequest request = new FenXiaoGetProductsRequest();
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                PageList<FenxiaoProduct> products = Client.FenXiaoGetProducts(request, SessionKey);
                OutputWriter.WriteLine("一共有：" + products.TotalResults + "条产品需要更新：", OutputFormatType.Title);

                ProcessPageList<FenxiaoProduct>("产品信息", request.PageSize.Value, products,
                    (pageNo) =>
                    {
                        request.PageNo = pageNo;
                        return Client.FenXiaoGetProducts(request, SessionKey);
                    },
                    SaveFenXiaoProduct);

            }
            catch (Exception e)
            {
                HandleException("更新产品信息异常", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新产品信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        protected void UpdateProductCats()
        {
            ExcuteUpdateStatus("正在更新产品线信息");

            try
            {
                OutputWriter.WriteLine("开始更新产品线信息...", OutputFormatType.Title);
                FenXiaoGetProductCatsRequest request = new FenXiaoGetProductCatsRequest();
                request.Fields = "total_results,productcats";
                PageList<ProductCat> productCats = Client.FenXiaoGetProductCats(request, SessionKey);
                List<ProductCat> allProductCates = productCats.Content;

                OutputWriter.WriteLine("一共有：" + allProductCates.Count + "条产品线需要更新：", OutputFormatType.Title);

                foreach (ProductCat pcat in allProductCates)
                {
                    SaveProductCat(pcat);
                }
            }
            catch (Exception e)
            {
                HandleException("更新产品线异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新产品线信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        #endregion

        #region Update PurchaseOrder and SubPurchaseOrder from the trade

        protected bool UpdateTradeInfoFromTAOBAO(Model.Trade trade)
        {
            if (trade ==null )
                return false;

            var nonRealTrade = IsNonRealTrade(trade);
            if (!nonRealTrade)
            {
                try
                {
                    TradeFullinfoGetRequest request = new TradeFullinfoGetRequest();
                    request.Tid = trade.tid;
                    request.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, num_iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                    Trade fullTTrade = Client.TradeFullinfoGet(request, SessionKey);
                    SaveTrade(fullTTrade, true);
                }
                catch (Exception te)
                {
                    HandleException("从淘宝获取分销交易：" + trade + " 的详细信息失败。", te, true);
                }
            }

            PurchaseOrder tPOder = null;
            bool result = false;

            try
            {
                FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                request.PurchaseOrderID = trade.tid;
                PageList<PurchaseOrder> purchaseOrders = Client.FenXiaoGetOrders(request, SessionKey);
                if (purchaseOrders.Content.Count > 0)
                {
                    tPOder = purchaseOrders.Content[0];
                    if (nonRealTrade)
                    {
                        UpdateNonRealTrade(trade.tid, tPOder);
                    }
                    result = SavePurchaseOrder(tPOder, true);
                }
            }
            catch (Exception e)
            {
                HandleException("从淘宝获取分销采购单：" + trade + " 的详细信息失败。", e, true);
                return false;
            }

            if (tPOder != null && result )
            {
                if (ResourceManager.Current.OptionsConfig.updateDetailOrder)
                {
                    foreach (SubPurchaseOrder subPOrder in tPOder.SubPurchaseOrders)
                    {
                        SaveSubPurchaseOrder(tPOder.ID, subPOrder, true);
                    }
                }
                return true; 
            }

            return false;
        }

        protected void UpdateNotFinishedTradeInfosFromTAOBAO()
        {
            long total = 0, success = 0;
            string title = "未结束的分销采购单的详细信息";
            ExcuteUpdateStatus("正在更新本地未结束的分销采购单的详细信息...");
            try
            {
                List<Model.Trade> dTradeList = new List<Model.Trade>();
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    OutputWriter.WriteLine("开始更新所有未结束的分销采购单的详细信息...", OutputFormatType.Title);
                    dTradeList = (from t in entities.Trade
                                where t.Shop.ShopId == ShopID
                                && (t.status != Constants.PurchaseOrder_TRADE_CLOSED
                                    && t.status != Constants.PurchaseOrder_TRADE_CLOSED_BY_TAOBAO
                                    && t.status != Constants.PurchaseOrder_TRADE_FINISHED)
                                select t).ToList();
                }

                LogstatisticsStart(title, total = dTradeList.Count);
                foreach (var trade in dTradeList)
                {
                    if (UpdateTradeInfoFromTAOBAO(trade))
                        success++;
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        protected void UpdateNonRealTrade(long tradeId, PurchaseOrder purchaseOrder)
        {
            using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
            {
                var dTrade = (from o in entities.Trade
                                           where o.tid == tradeId
                                              && o.Shop.ShopId == ShopID
                                              select o).FirstOrDefault();
                if (dTrade != null)
                {
                    CopyPurchaseOrderToDbTrade(purchaseOrder, dTrade, GetShop(entities, ShopID));
                    entities.SaveChanges();
                }
            }
        }
        #endregion

        #region Update Trade Rate

        protected bool NeedUpdateTradeRates(short shopid)
        {
            return true;
            //bool result = false;
            //using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
            //{
            //    var shop = (from s in entities.Shop
            //                where s.ShopId == shopid
            //                select s).FirstOrDefault();
            //    if (shop != null)
            //    {
            //        if (shop.LatestTradeRateUpdate.HasValue)
            //        {
            //            var latestUpdateDate = shop.LatestTradeRateUpdate.Value;
            //            result = latestUpdateDate.Date != DateTime.Now.Date;
            //        }
            //        else
            //        {
            //            result = true;
            //        }
            //    }
            //}
            //return result;
        }

        public void ExcuteUpdateTradeRates()
        {
            try
            {
                if (NeedUpdateTradeRates(ShopID))
                {
                    UpdateTradeRates();
                    //using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                    //{
                    //    var shop = (from s in entities.Shop
                    //                where s.ShopId == ShopID
                    //                select s).FirstOrDefault();
                    //    shop.LatestTradeRateUpdate = DateTime.Now;
                    //    entities.SaveChanges();
                    //}
                } 
            }
            catch (Exception e)
            {
                HandleException("执行更新评价失败", e);
            }
        }

        public void UpdateTradeRates()
        {
            long total = 0;
            long success = 0;
            string title = "交易的评价信息";
            ExcuteUpdateStatus("正在更新交易的评价信息");
            try
            {
                OutputWriter.WriteLine("开始更新交易的评价信息！", OutputFormatType.Title);

                TraderatesGetRequest request = new TraderatesGetRequest();
                request.PageSize = 100;
                request.Fields = "tid,oid,role,nick,result,created,rated_nick,item_title,item_price,content,reply";
                request.Role = "buyer";
                request.RateType = "get";
                PageList<TradeRate> firstTradeRates = Client.TraderatesGet(request, SessionKey);

                long totalCount = ResourceManager.Current.OptionsConfig.traderatecount;
                total = (totalCount == -1 || totalCount > firstTradeRates.TotalResults) ? firstTradeRates.TotalResults : totalCount;

                 LogstatisticsStart(title, total );

                 success = ProcessPageList<TradeRate>("交易的评价信息", request.PageSize.Value, firstTradeRates,
                     (pageNo) =>
                     {
                         request.PageNo = pageNo;
                         return Client.TraderatesGet(request, SessionKey);
                     },
                     SaveTradeRate, total);

            }
            catch (Exception e)
            {
                HandleException("更新分销交易的评价信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
            }
        }

        private bool SaveTradeRate(Taobao.Top.Api.Domain.TradeRate tTradeRate)
        {
            try
            {
                using (Model.taobaodbEntities entities = ResourceManager.LoadEntity())
                {
                    Model.TradeRate dTradeRate = (from tr in entities.TradeRate 
                                                  where tr.Shop !=null 
                                                  &&  tr.Shop.ShopId ==ShopID
                                                  &&  tr.tid == tTradeRate.Tid
                                                      select tr).FirstOrDefault();
                    bool addRecord = dTradeRate == null;
                    if (addRecord)
                    {
                        dTradeRate = new Model.TradeRate();
                    }
                    dTradeRate.content = tTradeRate.Content;
                    dTradeRate.created = ConvertDateTime(tTradeRate.Created);
                    dTradeRate.item_price = (new Converter<string, double?>(p => {
                        double price = 0;
                        if (String.IsNullOrEmpty(p) || !double.TryParse(p,out price))
                            return null;
                        return price;
                                            }))(tTradeRate.ItemPrice);

                    dTradeRate.item_title = tTradeRate.ItemTitle;
                    dTradeRate.nick = tTradeRate.Nick;
                    dTradeRate.oid = tTradeRate.Oid;
                    dTradeRate.rated_nick = tTradeRate.RatedNick;
                    dTradeRate.reply = tTradeRate.Reply;
                    dTradeRate.result = tTradeRate.Result;
                    dTradeRate.role = tTradeRate.Role;
                    dTradeRate.tid = tTradeRate.Tid;
                    dTradeRate.Shop = GetShop(entities,ShopID);

                    StringBuilder message = new StringBuilder();
                    if (addRecord)
                    {
                        entities.AddToTradeRate(dTradeRate);
                        entities.SaveChanges();
                        message.AppendFormat("获得新的交易:{0}的评价信息.", tTradeRate.Tid);
                    }
                    else
                    {
                        entities.SaveChanges();
                        message.AppendFormat("更新交易:{0}的评价信息.", tTradeRate.Tid);
                    }
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                }
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新交易:" + tTradeRate.Tid + "的评价信息到数据库失败！", e);
            } 
            return false;
        }

        #endregion

        private bool IsNonRealTrade(Model.Trade trade)
        {
            return string.IsNullOrEmpty(trade.type);
        }

        private void CopyPurchaseOrderToDbTrade(PurchaseOrder purchaseOrder, Model.Trade dTrade,Model.Shop shop)
        {
            dTrade.Shop = shop;
            dTrade.status = purchaseOrder.Status;
            dTrade.created = ConvertDateTime(purchaseOrder.Created);
            if (purchaseOrder.Receiver != null)
            {
                dTrade.receiver_address = purchaseOrder.Receiver.Address;
                dTrade.receiver_city = purchaseOrder.Receiver.City;
                dTrade.receiver_district = purchaseOrder.Receiver.District;
                dTrade.receiver_mobile = purchaseOrder.Receiver.MobilePhone;
                dTrade.receiver_name = purchaseOrder.Receiver.Name;
                dTrade.receiver_phone = purchaseOrder.Receiver.Phone;
                dTrade.receiver_state = purchaseOrder.Receiver.State;
                dTrade.receiver_zip = purchaseOrder.Receiver.Zip;
            }
            //dTrade.total_fee = purchaseOrder.TotalFee.ToString();
            //dTrade.post_fee = purchaseOrder.PostFee.ToString();
            //dTrade.payment = purchaseOrder.DistributorPayment;
            //dTrade.buyer_memo = purchaseOrder.DistributorMemo;
        }
        
    }
}
